home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-24 | 27.5 KB | 1,018 lines | [TEXT/ttxt] |
- (*Assembler and interpreter of Pascal code*)
- (*K. Jensen, N. Wirth, Ch. Jacobi, ETH May 76*)
-
- program pcode(input,output,prd,prr);
-
- (* Note for the implementation.
- ===========================
- This interpreter is written for the case where all the fundamental types
- take one storage unit.
- In an actual implementation, the handling of the sp pointer has to take
- into account the fact that the types may have lengths different from one:
- in push and pop operations the sp has to be increased and decreased not
- by 1, but by a number depending on the type concerned.
- However, where the number of units of storage has been computed by the
- compiler, the value must not be corrected, since the lengths of the types
- involved have already been taken into account.
- *)
-
-
- label 1;
- const codemax = 8650;
- pcmax = 17500;
- maxstk = 13650; (* size of variable store *)
- overi = 13655; (* size of integer constant table = 5 *)
- overr = 13660; (* size of real constant table = 5 *)
- overs = 13730; (* size of set constant table = 70 *)
- overb = 13820;
- overm = 18000;
- maxstr = 18001;
- largeint = 26144;
- begincode = 3;
- inputadr = 5;
- outputadr = 6;
- prdadr = 7;
- prradr = 8;
- duminst = 62;
-
- type bit4 = 0..15;
- bit6 = 0..127;
- bit20 = -26143..26143;
- datatype = (undef,int,reel,bool,sett,adr,mark,car);
- address = -1..maxstr;
- beta = packed array[1..25] of char; (*error message*)
- settype = set of 0..58;
- alfa = packed array[1..10] of char;
-
- var code : array[0..codemax] of (* the program *)
- packed record op1 :bit6;
- p1 :bit4;
- q1 :bit20;
- op2 :bit6;
- p2 :bit4;
- q2 :bit20
- end;
- pc : 0..pcmax; (*program address register*)
- op : bit6; p : bit4; q : bit20; (*instruction register*)
-
- store : array [0..overm] of
- record case datatype of
- int :(vi :integer);
- reel :(vr :real);
- bool :(vb :boolean);
- sett :(vs :settype);
- car :(vc :char);
- adr :(va :address);
- (*address in store*)
- mark :(vm :integer)
- end;
- mp,sp,np,ep : address; (* address registers *)
- (*mp points to beginning of a data segment
- sp points to top of the stack
- ep points to the maximum extent of the stack
- np points to top of the dynamically allocated area*)
-
- interpreting: boolean;
- prd,prr : text;(*prd for read only, prr for write only *)
-
- instr : array[bit6] of alfa; (* mnemonic instruction codes *)
- cop : array[bit6] of integer;
- sptable : array[0..20] of alfa; (*standard functions and procedures*)
-
- (*locally used for interpreting one instruction*)
- ad,ad1 : address;
- b : boolean;
- i,j,i1,i2 : integer;
- c : char;
-
- (*--------------------------------------------------------------------*)
-
- procedure load;
- const maxlabel = 1850;
- type labelst = (entered,defined); (*label situation*)
- labelrg = 0..maxlabel; (*label range*)
- labelrec = record
- val: address;
- st: labelst
- end;
- var icp,rcp,scp,bcp,mcp : address; (*pointers to next free position*)
- word : array[1..10] of char; i : integer; ch : char;
- labeltab: array[labelrg] of labelrec;
- labelvalue: address;
-
- procedure init;
- var i: integer;
- begin instr[ 0]:='lod '; instr[ 1]:='ldo ';
- instr[ 2]:='str '; instr[ 3]:='sro ';
- instr[ 4]:='lda '; instr[ 5]:='lao ';
- instr[ 6]:='sto '; instr[ 7]:='ldc ';
- instr[ 8]:='... '; instr[ 9]:='ind ';
- instr[10]:='inc '; instr[11]:='mst ';
- instr[12]:='cup '; instr[13]:='ent ';
- instr[14]:='ret '; instr[15]:='csp ';
- instr[16]:='ixa '; instr[17]:='equ ';
- instr[18]:='neq '; instr[19]:='geq ';
- instr[20]:='grt '; instr[21]:='leq ';
- instr[22]:='les '; instr[23]:='ujp ';
- instr[24]:='fjp '; instr[25]:='xjp ';
- instr[26]:='chk '; instr[27]:='eof ';
- instr[28]:='adi '; instr[29]:='adr ';
- instr[30]:='sbi '; instr[31]:='sbr ';
- instr[32]:='sgs '; instr[33]:='flt ';
- instr[34]:='flo '; instr[35]:='trc ';
- instr[36]:='ngi '; instr[37]:='ngr ';
- instr[38]:='sqi '; instr[39]:='sqr ';
- instr[40]:='abi '; instr[41]:='abr ';
- instr[42]:='not '; instr[43]:='and ';
- instr[44]:='ior '; instr[45]:='dif ';
- instr[46]:='int '; instr[47]:='uni ';
- instr[48]:='inn '; instr[49]:='mod ';
- instr[50]:='odd '; instr[51]:='mpi ';
- instr[52]:='mpr '; instr[53]:='dvi ';
- instr[54]:='dvr '; instr[55]:='mov ';
- instr[56]:='lca '; instr[57]:='dec ';
- instr[58]:='stp '; instr[59]:='ord ';
- instr[60]:='chr '; instr[61]:='ujc ';
-
- sptable[ 0]:='get '; sptable[ 1]:='put ';
- sptable[ 2]:='rst '; sptable[ 3]:='rln ';
- sptable[ 4]:='new '; sptable[ 5]:='wln ';
- sptable[ 6]:='wrs '; sptable[ 7]:='eln ';
- sptable[ 8]:='wri '; sptable[ 9]:='wrr ';
- sptable[10]:='wrc '; sptable[11]:='rdi ';
- sptable[12]:='rdr '; sptable[13]:='rdc ';
- sptable[14]:='sin '; sptable[15]:='cos ';
- sptable[16]:='exp '; sptable[17]:='log ';
- sptable[18]:='sqt '; sptable[19]:='atn ';
- sptable[20]:='sav ';
-
- cop[ 0] := 105; cop[ 1] := 65;
- cop[ 2] := 70; cop[ 3] := 75;
- cop[ 6] := 80; cop[ 9] := 85;
- cop[10] := 90; cop[26] := 95;
- cop[57] := 100;
-
- pc := begincode;
- icp := maxstk + 1;
- rcp := overi + 1;
- scp := overr + 1;
- bcp := overs + 2;
- mcp := overb + 1;
- for i:= 1 to 10 do word[i]:= ' ';
- for i:= 0 to maxlabel do
- with labeltab[i] do begin val:=-1; st:= entered end;
- reset(prd);
- end;(*init*)
-
- procedure errorl(string: beta); (*error in loading*)
- begin writeln;
- write(string);
- halt
- end; (*errorl*)
-
- procedure update(x: labelrg); (*when a label definition lx is found*)
- var curr,succ: -1..pcmax; (*resp. current element and successor element
- of a list of future references*)
- endlist: boolean;
- begin
- if labeltab[x].st=defined then errorl(' duplicated label ')
- else begin
- if labeltab[x].val<>-1 then (*forward reference(s)*)
- begin curr:= labeltab[x].val; endlist:= false;
- while not endlist do
- with code[curr div 2] do
- begin
- if odd(curr) then begin succ:= q2;
- q2:= labelvalue
- end
- else begin succ:= q1;
- q1:= labelvalue
- end;
- if succ=-1 then endlist:= true
- else curr:= succ
- end;
- end;
- labeltab[x].st := defined;
- labeltab[x].val:= labelvalue;
- end
- end;(*update*)
-
- procedure assemble; forward;
-
- procedure generate;(*generate segment of code*)
- var x: integer; (* label number *)
- again: boolean;
- begin
- again := true;
- while again do
- begin read(prd,ch);(* first character of line*)
- case ch of
- 'i': readln(prd);
- 'l': begin read(prd,x);
- if not eoln(prd) then read(prd,ch);
- if ch='=' then read(prd,labelvalue)
- else labelvalue:= pc;
- update(x); readln(prd);
- end;
- 'q': begin again := false; readln(prd) end;
- ' ': begin read(prd,ch); assemble end
- end;
- end
- end; (*generate*)
-
- procedure assemble; (*translate symbolic code into machine code and store*)
- label 1; (*goto 1 for instructions without code generation*)
- var name :alfa; b :boolean; r :real; s :settype;
- c1 :char; i,s1,lb,ub :integer;
-
- procedure lookup(x: labelrg); (* search in label table*)
- begin case labeltab[x].st of
- entered: begin q := labeltab[x].val;
- labeltab[x].val := pc
- end;
- defined: q:= labeltab[x].val
- end(*case label..*)
- end;(*lookup*)
-
- procedure labelsearch;
- var x: labelrg;
- begin while (ch<>'l') and not eoln(prd) do read(prd,ch);
- read(prd,x); lookup(x)
- end;(*labelsearch*)
-
- procedure getname;
- begin word[1] := ch;
- read(prd,word[2],word[3]);
- if not eoln(prd) then read(prd,ch) (*next character*);
- pack(word,1,name)
- end; (*getname*)
-
- procedure typesymbol;
- var i: integer;
- begin
- if ch <> 'i' then
- begin
- case ch of
- 'a': i := 0;
- 'r': i := 1;
- 's': i := 2;
- 'b': i := 3;
- 'c': i := 4;
- end;
- op := cop[op]+i;
- end;
- end (*typesymbol*) ;
-
- begin p := 0; q := 0; op := 0;
- getname;
- instr[duminst] := name;
- while instr[op]<>name do op := op+1;
- if op = duminst then errorl(' illegal instruction ');
-
- case op of (* get parameters p,q *)
-
- (*equ,neq,geq,grt,leq,les*)
- 17,18,19,
- 20,21,22: begin case ch of
- 'a': ; (*p = 0*)
- 'i': p := 1;
- 'r': p := 2;
- 'b': p := 3;
- 's': p := 4;
- 'c': p := 6;
- 'm': begin p := 5;
- read(prd,q)
- end
- end
- end;
-
- (*lod,str*)
- 0,2: begin typesymbol; read(prd,p,q)
- end;
-
- 4 (*lda*): read(prd,p,q);
-
- 12 (*cup*): begin read(prd,p); labelsearch end;
-
- 11 (*mst*): read(prd,p);
-
- 14 (*ret*): case ch of
- 'p': p:=0;
- 'i': p:=1;
- 'r': p:=2;
- 'c': p:=3;
- 'b': p:=4;
- 'a': p:=5
- end;
-
- (*lao,ixa,mov*)
- 5,16,55: read(prd,q);
-
- (*ldo,sro,ind,inc,dec*)
- 1,3,9,10,57: begin typesymbol; read(prd,q)
- end;
-
- (*ujp,fjp,xjp*)
- 23,24,25: labelsearch;
-
- 13 (*ent*): begin read(prd,p); labelsearch end;
-
- 15 (*csp*): begin for i:=1 to 9 do read(prd,ch); getname;
- while name<>sptable[q] do q := q+1
- end;
-
- 7 (*ldc*): begin case ch of (*get q*)
- 'i': begin p := 1; read(prd,i);
- if abs(i)>=largeint then
- begin op := 8;
- store[icp].vi := i; q := maxstk;
- repeat q := q+1 until store[q].vi=i;
- if q=icp then
- begin icp := icp+1;
- if icp=overi then
- errorl(' integer table overflow ');
- end
- end else q := i
- end;
-
- 'r': begin op := 8; p := 2;
- read(prd,r);
- store[rcp].vr := r; q := overi;
- repeat q := q+1 until store[q].vr=r;
- if q=rcp then
- begin rcp := rcp+1;
- if rcp = overr then
- errorl(' real table overflow ');
- end
- end;
-
- 'n': ; (*p,q = 0*)
-
- 'b': begin p := 3; read(prd,q) end;
-
- 'c': begin p := 6;
- repeat read(prd,ch); until ch <> ' ';
- if ch <> '''' then
- errorl(' illegal character ');
- read(prd,ch); q := ord(ch);
- read(prd,ch);
- if ch <> '''' then
- errorl(' illegal character ');
- end;
- '(': begin op := 8; p := 4;
- s := [ ]; read(prd,ch);
- while ch<>')' do
- begin read(prd,s1,ch); s := s + [s1]
- end;
- store[scp].vs := s; q := overr;
- repeat q := q+1 until store[q].vs=s;
- if q=scp then
- begin scp := scp+1;
- if scp=overs then
- errorl(' set table overflow ');
- end
- end
- end (*case*)
- end;
-
- 26 (*chk*): begin typesymbol;
- read(prd,lb,ub);
- if op = 95 then q := lb
- else
- begin
- store[bcp-1].vi := lb; store[bcp].vi := ub;
- q := overs;
- repeat q := q+2
- until (store[q-1].vi=lb)and (store[q].vi=ub);
- if q=bcp then
- begin bcp := bcp+2;
- if bcp=overb then
- errorl(' boundary table overflow ');
- end
- end
- end;
-
- 56 (*lca*): begin
- if mcp + 16 >= overm then
- errorl(' multiple table overflow ');
- mcp := mcp+16;
- q := mcp;
- for i := 0 to 15 (*stringlgth*) do
- begin read(prd,ch);
- store[q+i].vc := ch
- end;
- end;
-
- 6 (*sto*): typesymbol;
-
- 27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,58: ;
-
- (*ord,chr*)
- 59,60: goto 1;
-
- 61 (*ujc*): ; (*must have same length as ujp*)
-
- end; (*case*)
-
- (* store instruction *)
- with code[pc div 2] do
- if odd(pc) then
- begin op2 := op; p2 := p; q2 := q
- end else
- begin op1 := op; p1 := p; q1 := q
- end;
- pc := pc+1;
- 1: readln(prd);
- end; (*assemble*)
-
- begin (*load*)
- init;
- generate;
- pc := 0;
- generate;
- end; (*load*)
-
- (*------------------------------------------------------------------------*)
-
- procedure pmd;
- var s :integer; i: integer;
-
- procedure pt;
- begin write(s:6);
- if abs(store[s].vi) < maxint then write(store[s].vi)
- else write('too big ');
- s := s - 1;
- i := i + 1;
- if i = 4 then
- begin writeln(output); i := 0 end;
- end; (*pt*)
-
- begin
- write(' pc =',pc-1:5,' op =',op:3,' sp =',sp:5,' mp =',mp:5,
- ' np =',np:5);
- writeln; writeln('--------------------------------------');
-
- s := sp; i := 0;
- while s>=0 do pt;
- s := maxstk;
- while s>=np do pt;
- end; (*pmd*)
-
- procedure errori(string: beta);
- begin writeln; writeln(string);
- pmd; goto 1
- end;(*errori*)
-
- function base(ld :integer):address;
- var ad :address;
- begin ad := mp;
- while ld>0 do
- begin ad := store[ad+1].vm; ld := ld-1
- end;
- base := ad
- end; (*base*)
-
- procedure compare;
- (*comparing is only correct if result by comparing integers will be*)
- begin
- i1 := store[sp].va;
- i2 := store[sp+1].va;
- i := 0; b := true;
- while b and (i<>q) do
- if store[i1+i].vi = store[i2+i].vi then i := i+1
- else b := false
- end; (*compare*)
-
- procedure callsp;
- var line: boolean; adptr,adelnt: address;
- i: integer;
-
- procedure readi(var f:text);
- var ad: address;
- begin ad:= store[sp-1].va;
- read(f,store[ad].vi);
- store[store[sp].va].vc := f^;
- sp:= sp-2
- end;(*readi*)
-
- procedure readr(var f: text);
- var ad: address;
- begin ad:= store[sp-1].va;
- read(f,store[ad].vr);
- store[store[sp].va].vc := f^;
- sp:= sp-2
- end;(*readr*)
-
- procedure readc(var f: text);
- var c: char; ad: address;
- begin read(f,c);
- ad:= store[sp-1].va;
- store[ad].vc := c;
- store[store[sp].va].vc := f^;
- store[store[sp].va].vi := ord(f^);
- sp:= sp-2
- end;(*readc*)
-
- procedure writestr(var f: text);
- var i,j,k: integer;
- ad: address;
- begin ad:= store[sp-3].va;
- k := store[sp-2].vi; j := store[sp-1].vi;
- (* j and k are numbers of characters *)
- if k>j then for i:=1 to k-j do write(f,' ')
- else j:= k;
- for i := 0 to j-1 do write(f,store[ad+i].vc);
- sp:= sp-4
- end;(*writestr*)
-
- procedure getfile(var f: text);
- var ad: address;
- begin ad:=store[sp].va;
- get(f); store[ad].vc := f^;
- sp:=sp-1
- end;(*getfile*)
-
- procedure putfile(var f: text);
- var ad: address;
- begin ad:= store[sp].va;
- f^:= store[ad].vc; put(f);
- sp:= sp-1;
- end;(*putfile*)
-
- begin (*callsp*)
- case q of
- 0 (*get*): case store[sp].va of
- 5: getfile(input);
- 6: errori(' get on output file ');
- 7: getfile(prd);
- 8: errori(' get on prr file ')
- end;
- 1 (*put*): case store[sp].va of
- 5: errori(' put on read file ');
- 6: putfile(output);
- 7: errori(' put on prd file ');
- 8: putfile(prr)
- end;
- 2 (*rst*): begin
- (*for testphase*)
- np := store[sp].va; sp := sp-1
- end;
- 3 (*rln*): begin case store[sp].va of
- 5: begin readln(input);
- store[inputadr].vc := input^
- end;
- 6: errori(' readln on output file ');
- 7: begin readln(input);
- store[inputadr].vc := input^
- end;
- 8: errori(' readln on prr file ')
- end;
- sp:= sp-1
- end;
- 4 (*new*): begin ad:= np-store[sp].va;
- (*top of stack gives the length in units of storage *)
- if ad <= ep then
- errori(' store overflow ');
- np:= ad; ad:= store[sp-1].va;
- store[ad].va := np;
- sp:=sp-2
- end;
- 5 (*wln*): begin case store[sp].va of
- 5: errori(' writeln on input file ');
- 6: writeln(output);
- 7: errori(' writeln on prd file ');
- 8: writeln(prr)
- end;
- sp:= sp-1
- end;
- 6 (*wrs*): case store[sp].va of
- 5: errori(' write on input file ');
- 6: writestr(output);
- 7: errori(' write on prd file ');
- 8: writestr(prr)
- end;
- 7 (*eln*): begin case store[sp].va of
- 5: line:= eoln(input);
- 6: errori(' eoln output file ');
- 7: line:=eoln(prd);
- 8: errori(' eoln on prr file ')
- end;
- store[sp].vb := line
- end;
- 8 (*wri*): begin case store[sp].va of
- 5: errori(' write on input file ');
- 6: write(output,
- store[sp-2].vi: store[sp-1].vi);
- 7: errori(' write on prd file ');
- 8: write(prr,
- store[sp-2].vi: store[sp-1].vi)
- end;
- sp:=sp-3
- end;
- 9 (*wrr*): begin case store[sp].va of
- 5: errori(' write on input file ');
- 6: write(output,
- store[sp-2].vr: store[sp-1].vi);
- 7: errori(' write on prd file ');
- 8: write(prr,
- store[sp-2].vr: store[sp-1].vi)
- end;
- sp:=sp-3
- end;
- 10(*wrc*): begin case store[sp].va of
- 5: errori(' write on input file ');
- 6: write(output,store[sp-2].vc:
- store[sp-1].vi);
- 7: errori(' write on prd file ');
- 8: write(prr,chr(store[sp-2].vi):
- store[sp-1].vi);
- end;
- sp:=sp-3
- end;
- 11(*rdi*): case store[sp].va of
- 5: readi(input);
- 6: errori(' read on output file ');
- 7: readi(prd);
- 8: errori(' read on prr file ')
- end;
- 12(*rdr*): case store[sp].va of
- 5: readr(input);
- 6: errori(' read on output file ');
- 7: readr(prd);
- 8: errori(' read on prr file ')
- end;
- 13(*rdc*): case store[sp].va of
- 5: readc(input);
- 6: errori(' read on output file ');
- 7: readc(prd);
- 8: errori(' read on prr file ')
- end;
- 14(*sin*): store[sp].vr:= sin(store[sp].vr);
- 15(*cos*): store[sp].vr:= cos(store[sp].vr);
- 16(*exp*): store[sp].vr:= exp(store[sp].vr);
- 17(*log*): store[sp].vr:= ln(store[sp].vr);
- 18(*sqt*): store[sp].vr:= sqrt(store[sp].vr);
- 19(*atn*): store[sp].vr:= arctan(store[sp].vr);
- 20(*sav*): begin ad:=store[sp].va;
- store[ad].va := np;
- sp:= sp-1
- end;
- end;(*case q*)
- end;(*callsp*)
-
- begin (* main *)
- rewrite(prr);
- load; (* assembles and stores code *)
- (* writeln(output); for testing *)
- pc := 0; sp := -1; mp := 0; np := maxstk+1; ep := 5;
- store[inputadr].vc := input^;
- store[prdadr].vc := prd^;
- interpreting := true;
-
- while interpreting do
- begin
- (*fetch*)
- with code[pc div 2] do
- if odd(pc) then
- begin op := op2; p := p2; q := q2
- end else
- begin op := op1; p := p1; q := q1
- end;
- pc := pc+1;
-
- (*execute*)
- case op of
-
- 105,106,107,108,109,
- 0 (*lod*): begin ad := base(p) + q;
- sp := sp+1;
- store[sp] := store[ad]
- end;
-
- 65,66,67,68,69,
- 1 (*ldo*): begin
- sp := sp+1;
- store[sp] := store[q]
- end;
-
- 70,71,72,73,74,
- 2 (*str*): begin store[base(p)+q] := store[sp];
- sp := sp-1
- end;
-
- 75,76,77,78,79,
- 3 (*sro*): begin store[q] := store[sp];
- sp := sp-1
- end;
-
- 4 (*lda*): begin sp := sp+1;
- store[sp].va := base(p) + q
- end;
-
- 5 (*lao*): begin sp := sp+1;
- store[sp].va := q
- end;
-
- 80,81,82,83,84,
- 6 (*sto*): begin
- store[store[sp-1].va] := store[sp];
- sp := sp-2;
- end;
-
- 7 (*ldc*): begin sp := sp+1;
- if p=1 then
- begin store[sp].vi := q;
- end else
- if p = 6 then store[sp].vc := chr(q)
- else
- if p = 3 then store[sp].vb := q = 1
- else (* load nil *) store[sp].va := maxstr
- end;
-
- 8 (*lci*): begin sp := sp+1;
- store[sp] := store[q]
- end;
-
- 85,86,87,88,89,
- 9 (*ind*): begin ad := store[sp].va + q;
- (* q is a number of storage units *)
- store[sp] := store[ad]
- end;
-
- 90,91,92,93,94,
- 10 (*inc*): store[sp].vi := store[sp].vi+q;
-
- 11 (*mst*): begin (*p=level of calling procedure minus level of called
- procedure + 1; set dl and sl, increment sp*)
- (* then length of this element is
- max(intsize,realsize,boolsize,charsize,ptrsize *)
- store[sp+2].vm := base(p);
- (* the length of this element is ptrsize *)
- store[sp+3].vm := mp;
- (* idem *)
- store[sp+4].vm := ep;
- (* idem *)
- sp := sp+5
- end;
-
- 12 (*cup*): begin (*p=no of locations for parameters, q=entry point*)
- mp := sp-(p+4);
- store[mp+4].vm := pc;
- pc := q
- end;
-
- 13 (*ent*): if p = 1 then
- begin sp := mp + q; (*q = length of dataseg*)
- if sp > np then errori(' store overflow ');
- end
- else
- begin ep := sp+q;
- if ep > np then errori(' store overflow ');
- end;
- (*q = max space required on stack*)
-
- 14 (*ret*): begin case p of
- 0: sp:= mp-1;
- 1,2,3,4,5: sp:= mp
- end;
- pc := store[mp+4].vm;
- ep := store[mp+3].vm;
- mp:= store[mp+2].vm;
- end;
-
- 15 (*csp*): callsp;
-
- 16 (*ixa*): begin
- i := store[sp].vi;
- sp := sp-1;
- store[sp].va := q*i+store[sp].va;
- end;
-
- 17 (*equ*): begin sp := sp-1;
- case p of
- 1: store[sp].vb := store[sp].vi = store[sp+1].vi;
- 0: store[sp].vb := store[sp].va = store[sp+1].va;
- 6: store[sp].vb := store[sp].vc = store[sp+1].vc;
- 2: store[sp].vb := store[sp].vr = store[sp+1].vr;
- 3: store[sp].vb := store[sp].vb = store[sp+1].vb;
- 4: store[sp].vb := store[sp].vs = store[sp+1].vs;
- 5: begin compare;
- store[sp].vb := b;
- end;
- end; (*case p*)
- end;
-
- 18 (*neq*): begin sp := sp-1;
- case p of
- 0: store[sp].vb := store[sp].va <> store[sp+1].va;
- 1: store[sp].vb := store[sp].vi <> store[sp+1].vi;
- 6: store[sp].vb := store[sp].vc <> store[sp+1].vc;
- 2: store[sp].vb := store[sp].vr <> store[sp+1].vr;
- 3: store[sp].vb := store[sp].vb <> store[sp+1].vb;
- 4: store[sp].vb := store[sp].vs <> store[sp+1].vs;
- 5: begin compare;
- store[sp].vb := not b;
- end
- end; (*case p*)
- end;
-
- 19 (*geq*): begin sp := sp-1;
- case p of
- 0: errori(' <,<=,>,>= for address ');
- 1: store[sp].vb := store[sp].vi >= store[sp+1].vi;
- 6: store[sp].vb := store[sp].vc >= store[sp+1].vc;
- 2: store[sp].vb := store[sp].vr >= store[sp+1].vr;
- 3: store[sp].vb := store[sp].vb >= store[sp+1].vb;
- 4: store[sp].vb := store[sp].vs >= store[sp+1].vs;
- 5: begin compare;
- store[sp].vb := b or
- (store[i1+i].vi >= store[i2+i].vi)
- end
- end; (*case p*)
- end;
-
- 20 (*grt*): begin sp := sp-1;
- case p of
- 0: errori(' <,<=,>,>= for address ');
- 1: store[sp].vb := store[sp].vi > store[sp+1].vi;
- 6: store[sp].vb := store[sp].vc > store[sp+1].vc;
- 2: store[sp].vb := store[sp].vr > store[sp+1].vr;
- 3: store[sp].vb := store[sp].vb > store[sp+1].vb;
- 4: errori(' set inclusion ');
- 5: begin compare;
- store[sp].vb := not b and
- (store[i1+i].vi > store[i2+i].vi)
- end
- end; (*case p*)
- end;
-
- 21 (*leq*): begin sp := sp-1;
- case p of
- 0: errori(' <,<=,>,>= for address ');
- 1: store[sp].vb := store[sp].vi <= store[sp+1].vi;
- 6: store[sp].vb := store[sp].vc <= store[sp+1].vc;
- 2: store[sp].vb := store[sp].vr <= store[sp+1].vr;
- 3: store[sp].vb := store[sp].vb <= store[sp+1].vb;
- 4: store[sp].vb := store[sp].vs <= store[sp+1].vs;
- 5: begin compare;
- store[sp].vb := b or
- (store[i1+i].vi <= store[i2+i].vi)
- end;
- end; (*case p*)
- end;
-
- 22 (*les*): begin sp := sp-1;
- case p of
- 0: errori(' <,<=,>,>= for address ');
- 1: store[sp].vb := store[sp].vi < store[sp+1].vi;
- 6: store[sp].vb := store[sp].vc < store[sp+1].vc;
- 2: store[sp].vb := store[sp].vr < store[sp+1].vr;
- 3: store[sp].vb := store[sp].vb < store[sp+1].vb;
- 5: begin compare;
- store[sp].vb := not b and
- (store[i1+i].vi < store[i2+i].vi)
- end
- end; (*case p*)
- end;
-
- 23 (*ujp*): pc := q;
-
- 24 (*fjp*): begin if not store[sp].vb then pc := q;
- sp := sp-1
- end;
-
- 25 (*xjp*): begin
- pc := store[sp].vi + q;
- sp := sp-1
- end;
-
- 95 (*chka*): if (store[sp].va < np) or
- (store[sp].va > (maxstr-q)) then
- errori(' bad pointer value ');
-
- 96,97,98,99,
- 26 (*chk*): if (store[sp].vi < store[q-1].vi) or
- (store[sp].vi > store[q].vi) then
- errori(' value out of range ');
-
- 27 (*eof*): begin i := store[sp].vi;
- if i=inputadr then
- begin store[sp].vb := eof(input);
- end else errori(' code in error ')
- end;
-
- 28 (*adi*): begin sp := sp-1;
- store[sp].vi := store[sp].vi + store[sp+1].vi
- end;
-
- 29 (*adr*): begin sp := sp-1;
- store[sp].vr := store[sp].vr + store[sp+1].vr
- end;
-
- 30 (*sbi*): begin sp := sp-1;
- store[sp].vi := store[sp].vi - store[sp+1].vi
- end;
-
- 31 (*sbr*): begin sp := sp-1;
- store[sp].vr := store[sp].vr - store[sp+1].vr
- end;
-
- 32 (*sgs*): store[sp].vs := [store[sp].vi];
-
- 33 (*flt*): store[sp].vr := store[sp].vi;
-
- 34 (*flo*): store[sp-1].vr := store[sp-1].vi;
-
- 35 (*trc*): store[sp].vi := trunc(store[sp].vr);
-
- 36 (*ngi*): store[sp].vi := -store[sp].vi;
-
- 37 (*ngr*): store[sp].vr := -store[sp].vr;
-
- 38 (*sqi*): store[sp].vi := sqr(store[sp].vi);
-
- 39 (*sqr*): store[sp].vr := sqr(store[sp].vr);
-
- 40 (*abi*): store[sp].vi := abs(store[sp].vi);
-
- 41 (*abr*): store[sp].vr := abs(store[sp].vr);
-
- 42 (*not*): store[sp].vb := not store[sp].vb;
-
- 43 (*and*): begin sp := sp-1;
- store[sp].vb := store[sp].vb and store[sp+1].vb
- end;
-
- 44 (*ior*): begin sp := sp-1;
- store[sp].vb := store[sp].vb or store[sp+1].vb
- end;
-
- 45 (*dif*): begin sp := sp-1;
- store[sp].vs := store[sp].vs - store[sp+1].vs
- end;
-
- 46 (*int*): begin sp := sp-1;
- store[sp].vs := store[sp].vs * store[sp+1].vs
- end;
-
- 47 (*uni*): begin sp := sp-1;
- store[sp].vs := store[sp].vs + store[sp+1].vs
- end;
-
- 48 (*inn*): begin
- sp := sp - 1; i := store[sp].vi;
- store[sp].vb := i in store[sp+1].vs;
- end;
-
- 49 (*mod*): begin sp := sp-1;
- store[sp].vi := store[sp].vi mod store[sp+1].vi
- end;
-
- 50 (*odd*): store[sp].vb := odd(store[sp].vi);
-
- 51 (*mpi*): begin sp := sp-1;
- store[sp].vi := store[sp].vi * store[sp+1].vi
- end;
-
- 52 (*mpr*): begin sp := sp-1;
- store[sp].vr := store[sp].vr * store[sp+1].vr
- end;
-
- 53 (*dvi*): begin sp := sp-1;
- store[sp].vi := store[sp].vi div store[sp+1].vi
- end;
-
- 54 (*dvr*): begin sp := sp-1;
- store[sp].vr := store[sp].vr / store[sp+1].vr
- end;
-
- 55 (*mov*): begin i1 := store[sp-1].va;
- i2 := store[sp].va; sp := sp-2;
- for i := 0 to q-1 do store[i1+i] := store[i2+i]
- (* q is a number of storage units *)
- end;
-
- 56 (*lca*): begin sp := sp+1;
- store[sp].va := q;
- end;
-
- 100,101,102,103,104,
- 57 (*dec*): store[sp].vi := store[sp].vi-q;
-
- 58 (*stp*): interpreting := false;
-
- 59 (*ord*): (*only used to change the tagfield*)
- begin
- end;
-
- 60 (*chr*): begin
- end;
-
- 61 (*ujc*): errori(' case - error ');
- end
- end; (*while interpreting*)
-
- 1 :
- end.
-